package cn.nkpro.elcube.co;

import cn.nkpro.elcube.security.NkSecurityRunner;
import cn.nkpro.elcube.security.bo.UserDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.concurrent.Future;

@Component
public class NkAsyncInvoker {

    @Autowired@SuppressWarnings("all")
    private NkSecurityRunner securityRunner;

    /**
     * 以指定用户的权限，异步运行函数
     * @param user 用户
     * @param function 运行函数
     * @param <T> 返回参数
     * @return 返回值
     */
    @Async("nkTaskExecutor")
    public <T> Future<T> async(UserDetails user, Function<T> function){
        return securityRunner.returnAsUser(
                user,false, ()-> new AsyncResult<>(function.apply())
        );
    }

    /**
     * 以匿名方式异步运行函数
     * @param function 运行函数
     * @param <T> 返回参数
     * @return 返回值
     */
    @Async("nkTaskExecutor")
    public <T> Future<T> async(Function<T> function){
        return new AsyncResult<>(function.apply());
    }

    @FunctionalInterface
    public interface Function<T>{
        T apply();
    }
}
